home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_200 / 297_01 / prassert.c < prev    next >
C/C++ Source or Header  |  1980-01-01  |  7KB  |  309 lines

  1. /* prassert.c */
  2. /* implementation of assertz, asserta and clause handling
  3.  */
  4. #include <stdio.h>
  5. #include "prtypes.h"
  6. #include "prlex.h"
  7.  
  8. #define BADCOPYTYPE "Illegal data type in assert"
  9. #define NOTALIST "You did not give me a list"
  10. #define TAILNOTLIST "The tail is not a list"
  11. #define HEADNOTLIST "The head is not a list"
  12.  
  13. #ifndef SEGMENTED_ACHITECTURE
  14. #define IS_DYNAMIC(X) ((Dyn_mem <= (dyn_ptr_t)(X)) && ((dyn_ptr_t)(X)<HighDyn_ptr))
  15. #else
  16. #define IS_DYNAMIC(X) 1 /* implies you must make a fresh copy of each object */
  17. #endif
  18.  
  19. extern node_ptr_t DerefNode, NilNodeptr;
  20. extern subst_ptr_t DerefSubst;
  21. extern atom_ptr_t Nil;
  22. extern dyn_ptr_t Dyn_mem, HighDyn_ptr;
  23.  
  24. static char * VarSubsts[MAX_VAR];
  25. static varindx NVar_copied;
  26.  
  27. void ini_copy()
  28. {
  29.     NVar_copied = 0;
  30. }
  31.  
  32. /**********************************************************************
  33.             copy_clause() 
  34.  *********************************************************************/
  35. clause_ptr_t copy_clause(status, nodeptr, substptr, predptr)
  36. node_ptr_t nodeptr;/* represents the body of the clause */
  37. subst_ptr_t substptr;
  38. atom_ptr_t *predptr;
  39. {
  40.     void copy_node();
  41.     clause_ptr_t clauseptr, make_clause();
  42.     node_ptr_t clause_head, clause_tail, get_node();
  43.     objtype_t type;
  44.  
  45.     ini_copy();
  46.     dereference(nodeptr, substptr);
  47.     nodeptr = DerefNode;
  48.     substptr = DerefSubst;
  49.  
  50.     if(NODEPTR_TYPE(nodeptr) != PAIR)
  51.     {
  52.         errmsg(NOTALIST);
  53.         return(NULL);
  54.     }
  55.  
  56.     dereference(NODEPTR_HEAD(nodeptr), substptr);
  57.     type = NODEPTR_TYPE(DerefNode);
  58.     if(type != PAIR)
  59.     {
  60.         if(type == ATOM)
  61.         {
  62.             clause_head = get_node(status);
  63.             copy_node(status, clause_head, nodeptr, substptr);
  64.             clause_tail = NilNodeptr;
  65.             clauseptr = make_clause(clause_head, clause_tail, status, predptr);
  66.             return(clauseptr);
  67.         }
  68.         else
  69.             return(NULL);
  70.     }
  71.     else
  72.         clause_head = get_node(status);
  73.     copy_node(status, clause_head, DerefNode, DerefSubst);
  74.     dereference(NODEPTR_TAIL(nodeptr), substptr);
  75.  
  76.     if(IS_NIL(DerefNode))
  77.     {
  78.         clause_tail = NilNodeptr;
  79.     }
  80.     else
  81.         if(NODEPTR_TYPE(DerefNode) != PAIR)
  82.         {
  83.             errmsg(TAILNOTLIST);
  84.             return(NULL);
  85.         }
  86.         else
  87.         {
  88.             clause_tail = get_node(status);
  89.             copy_node(status, clause_tail, DerefNode, DerefSubst);
  90.         }
  91.  
  92.     clauseptr = make_clause(clause_head, clause_tail, status, predptr);
  93.     return(clauseptr);
  94. }
  95.  
  96. /*********************************************************************
  97.             copy_node()
  98.  **********************************************************************/
  99. void copy_node(status, target, source, substptr)
  100. node_ptr_t source, target;
  101. subst_ptr_t substptr;
  102. {
  103.     objtype_t type;
  104.     string_ptr_t stringptr, s, get_string();
  105. #ifdef REAL
  106.     real_ptr_t realptr, get_real();
  107. #endif
  108.     pair_ptr_t pairptr, get_pair();
  109.     char *molec;
  110.     int i;
  111.  
  112.     type = NODEPTR_TYPE(source);
  113.     NODEPTR_TYPE(target) = type;
  114.  
  115.     switch(type)
  116.     {
  117.     case ATOM:
  118.         NODEPTR_ATOM(target) = NODEPTR_ATOM(source);
  119.         break;
  120.  
  121.     case VAR:
  122.         molec = NODEPTR_OFFSET(source) + (char *)substptr;
  123.         for(i = 0; i < NVar_copied; i++)/*search molec in Varsubsts */
  124.         {
  125.             if(molec == VarSubsts[i])break;
  126.         }
  127.  
  128.         if(i == NVar_copied)/* it's new */
  129.         {
  130.             VarSubsts[i] = molec;
  131.             NVar_copied++;
  132.         }
  133.  
  134.         NODEPTR_OFFSET(target) = i * sizeof(struct subst);
  135.         break;
  136.  
  137.     case INT:
  138.         NODEPTR_INT(target) = NODEPTR_INT(source);
  139.         break;
  140. #ifdef CHARACTER
  141.     case CHARACTER:
  142.         NODEPTR_CHARACTER(target) = NODEPTR_CHARACTER(source);
  143.         break;
  144. #endif
  145. #ifdef REAL
  146.     case REAL:
  147.         if(IS_DYNAMIC(NODEPTR_REALP(source)))
  148.         {
  149.             realptr = get_real(status);
  150.             *realptr = NODEPTR_REAL(source);
  151.             NODEPTR_REALP(target) = realptr;
  152.         }
  153.         else
  154.         {
  155.             NODEPTR_REALP(target) = NODEPTR_REALP(source);
  156.         }
  157.         break;
  158. #endif
  159.     case PAIR:
  160.         pairptr = get_pair(status);
  161.         NODEPTR_PAIR(target) = pairptr;
  162.         dereference(NODEPTR_HEAD(source), substptr);
  163.         copy_node(status, NODEPTR_HEAD(target), DerefNode, DerefSubst);
  164.         dereference(NODEPTR_TAIL(source), substptr);
  165.         copy_node(status, NODEPTR_TAIL(target), DerefNode, DerefSubst);
  166.         break;
  167.  
  168.     case STRING:
  169.         s = NODEPTR_STRING(source);
  170.         if(IS_DYNAMIC(s))
  171.         {
  172.             if(status == PERMANENT)status = PERM_STRING;
  173.             stringptr = get_string((my_alloc_size_t)(strlen(s) + 1), status);
  174.             strcpy(stringptr, s);
  175.             NODEPTR_STRING(target) = stringptr;
  176.         }
  177.         else
  178.             NODEPTR_STRING(target) = s;
  179.         break;
  180.     default:
  181.         errmsg(BADCOPYTYPE);
  182.     }
  183. }
  184.  
  185. /*********************************************************************
  186.              do_assertz()
  187.  For the assertz builtin.
  188.  *********************************************************************/
  189. do_assertz(status, nodeptr, substptr)
  190. node_ptr_t nodeptr;
  191. subst_ptr_t substptr;
  192. {
  193.     clause_ptr_t clauseptr;
  194.     atom_ptr_t pred;
  195.  
  196.     clauseptr = copy_clause(status, nodeptr, substptr, &pred);
  197.  
  198.     if(clauseptr == NULL)
  199.         return(0);
  200.  
  201.     add_to_end(clauseptr, pred);
  202.     return(1);
  203. }
  204.  
  205. /*********************************************************************
  206.              do_asserta()
  207.  For the asserta builtin.
  208.  *********************************************************************/
  209. do_asserta(status, nodeptr, substptr)
  210. node_ptr_t nodeptr;
  211. subst_ptr_t substptr;
  212. {
  213.     clause_ptr_t clauseptr;
  214.     atom_ptr_t pred;
  215.  
  216.     clauseptr = copy_clause(status, nodeptr, substptr, &pred);
  217.  
  218.     if(clauseptr == NULL)
  219.         return(0);
  220.  
  221.     record_pred(pred);
  222.     CLAUSEPTR_NEXT(clauseptr) = ATOMPTR_CLAUSE(pred);
  223.     ATOMPTR_CLAUSE(pred) = clauseptr;
  224.     return(1);
  225. }
  226.  
  227. /******************************************************************************
  228.              do_assertn()
  229.  asserts a clause at the nth position if it can
  230.  n begins at 1.
  231.  ******************************************************************************/
  232. do_assertn(status, nodeptr, substptr, n)
  233. node_ptr_t nodeptr;
  234. subst_ptr_t substptr;
  235. integer n;
  236. {
  237.     clause_ptr_t clauseptr;
  238.     atom_ptr_t pred;
  239.  
  240.     if (n < 1)
  241.         return 0;
  242.     if (n == 1)
  243.         return(do_asserta(status, nodeptr, substptr));
  244.  
  245.     clauseptr = copy_clause(status, nodeptr, substptr, &pred);
  246.     if (clauseptr == NULL)
  247.         return 0;
  248.  
  249.     return (add_as_nth(clauseptr, pred, n));
  250. }
  251. /******************************************************************************
  252.             remove_clause()
  253.  ******************************************************************************/
  254. remove_clause(atomptr, clauseptr)
  255. atom_ptr_t atomptr;/* the predicate */
  256. clause_ptr_t clauseptr;/* remove this */
  257. {
  258.     if (clauseptr == ATOMPTR_CLAUSE(atomptr))
  259.     {
  260.         ATOMPTR_CLAUSE(atomptr) = CLAUSEPTR_NEXT(clauseptr);
  261.         return 1;
  262.     }
  263.     else
  264.     {
  265.         clause_ptr_t clp, previous;
  266.  
  267.         clp = ATOMPTR_CLAUSE(atomptr);
  268.         for(;;)
  269.         {
  270.             previous = clp;
  271.             clp = CLAUSEPTR_NEXT(clp);
  272.             if(clp == NULL)
  273.                 return 0;
  274.             if (clp == clauseptr)
  275.             {
  276.                 CLAUSEPTR_NEXT(previous) = CLAUSEPTR_NEXT(clp);
  277.                 return 1;
  278.             }
  279.         }
  280.     }
  281. }
  282.  
  283. /******************************************************************************
  284.              add_as_nth()
  285.  Tries to add a clause in the nth position of its packet.
  286.  Returns 0 iff unsuccessful.
  287.  ******************************************************************************/
  288. add_as_nth(clauseptr, pred, n)
  289. clause_ptr_t clauseptr;
  290. atom_ptr_t pred;
  291. integer n;
  292. {
  293.     clause_ptr_t clp;
  294.  
  295.     clp = ATOMPTR_CLAUSE(pred);
  296.     --n;
  297.  
  298.     while (--n >= 0)
  299.     {
  300.         clp = CLAUSEPTR_NEXT( clp);
  301.         if( clp == NULL)
  302.             return 0;
  303.     }
  304.     CLAUSEPTR_NEXT( clauseptr) = CLAUSEPTR_NEXT( clp );
  305.     CLAUSEPTR_NEXT( clp) = clauseptr;
  306.     return 1;
  307. }
  308. /* end of file */
  309.